Skip to content

Fixes #3023 - BREAKING CHANGE - Configurable key bindings via ConfigurationManager#4824

Merged
tig merged 82 commits intov2_developfrom
feature/cm-keybindings
Mar 13, 2026
Merged

Fixes #3023 - BREAKING CHANGE - Configurable key bindings via ConfigurationManager#4824
tig merged 82 commits intov2_developfrom
feature/cm-keybindings

Conversation

@tig
Copy link
Copy Markdown
Member

@tig tig commented Mar 10, 2026

Fixes

Summary

Makes all built-in key bindings configurable via ConfigurationManager with platform-specific support (Windows / Linux / macOS). The design is MEC-ready (Microsoft.Extensions.Configuration) to minimize future migration cost.

What Changed (140 files, +4065/-1368)

New infrastructure:

  • PlatformKeyBinding POCO record with All/Windows/Linux/Macos key slots
  • Bind factory class with ergonomic helpers: Bind.All(), Bind.AllPlus(), Bind.NonWindows(), Bind.Platform()
  • TuiPlatform enum replacing string-based platform identification
  • KeyBindingSchemaConverter for JSON serialization of Dictionary<Command, PlatformKeyBinding>
  • View.ApplyKeyBindings() — layered binding resolution using GetSupportedCommands() filter

Three [ConfigurationProperty] properties (the entire CM surface):

  1. Application.DefaultKeyBindings — app-level commands (Quit, Arrange, Tab navigation, Suspend, Refresh)
  2. View.DefaultKeyBindings — shared base layer (cursor nav, clipboard, selection, editing)
  3. View.ViewKeyBindings — per-view-type overrides merged dictionary

13 views migrated with view-specific DefaultKeyBindings:
TextField, TextView, ListView, TreeView, HexView, DropDownList, LinearRange, DateEditor, TimeEditor, TabView, TableView, CharMap, ColorPicker

Breaking changes (Phase 12):

  • Removed single-key properties from ApplicationKeyboard (QuitKey, ArrangeKey, NextTabStopKey, etc.) — replaced by Application.DefaultKeyBindings[Command.Quit] dictionary pattern
  • PlatformKeyBinding stores Key[] instead of string[] (type-safe)
  • Moved Bind and PlatformKeyBinding from Configuration/ to Input/Keyboard/
  • Application.GetDefaultKey(Command) and Application.GetDefaultKeys(Command) helper methods added

Other improvements:

  • Standardized MenuBar activation from F9→F10 (cross-platform consistency)
  • Fixed TextField Emacs keybindings (Ctrl+B/F) to bind on all platforms
  • Fixed Undo/Redo bindings to include Ctrl+Z/Y on all platforms
  • Added Configuration and Draw trace categories
  • Rewrote KeyBindings UICatalog scenario with 3-column layout

Architecture

┌──────────────────────────────────────────────────────────────┐
│  User config.json (overrides)                                │
│  "View.ViewKeyBindings": {                                   │
│    "TextField": { "Undo": { "All": ["Ctrl+Z"] } }           │
│  }                                                           │
└──────────────┬───────────────────────────────────────────────┘
               │ CM loads & replaces static property
               ▼
┌──────────────────────────────────────────────────────────────┐
│  C# Static Properties (source of truth)                      │
│  [ConfigurationProperty] — only 3 properties:                │
│                                                              │
│  Application.DefaultKeyBindings  ← Layer 1 (app-level)      │
│  View.DefaultKeyBindings         ← Layer 2 (shared base)    │
│  View.ViewKeyBindings            ← User overrides (merged)  │
│                                                              │
│  Plain statics (no [ConfigurationProperty]):                 │
│  TextField.DefaultKeyBindings    ← Layer 3 (view-specific)  │
│  ListView.DefaultKeyBindings     ← Layer 3 (view-specific)  │
│  ...                                                         │
└──────────────┬───────────────────────────────────────────────┘
               │ view.ApplyKeyBindings(layers...)
               ▼
┌──────────────────────────────────────────────────────────────┐
│  Platform Resolution (PlatformKeyBinding POCO)               │
│  Windows: All + Windows                                      │
│  Linux:   All + Linux                                        │
│  macOS:   All + Macos                                        │
└──────────────┬───────────────────────────────────────────────┘
               │ GetSupportedCommands() filter
               ▼
┌──────────────────────────────────────────────────────────────┐
│  view.KeyBindings.Add (key, command)                         │
│  Only for commands the view has registered handlers for      │
└──────────────────────────────────────────────────────────────┘

Design Principles

  • C# code is source of truth — defaults in static initializers, works without CM
  • config.json is for user overrides only — built-in config has zero key binding entries
  • Per-command platform attribution — each command specifies platform keys via PlatformKeyBinding
  • Skip unhandled commandsApplyKeyBindings() checks GetSupportedCommands() filter
  • MEC-ready POCOsPlatformKeyBinding maps cleanly to IOptions<T> binding

Example user config.json

{
  "Application.DefaultKeyBindings": {
    "Quit": { "All": ["Ctrl+Q"] },
    "Suspend": { "Linux": ["Ctrl+Z"], "Macos": ["Ctrl+Z"] }
  },
  "View.ViewKeyBindings": {
    "TextField": {
      "Undo": { "All": ["Ctrl+Z"] },
      "DeleteCharRight": { "All": ["Delete"], "Linux": ["Ctrl+D"], "Macos": ["Ctrl+D"] }
    }
  }
}

Documentation Updated

  • keyboard.md — rewrote for DefaultKeyBindings dictionary API
  • config.md — updated config examples and property references
  • navigation.md — replaced removed IKeyboard.*Key property refs
  • newinv2.md — updated v2 migration notes
  • arrangement.md, menus.md, migratingfromv1.md — fixed stale refs
  • example_config.json — comprehensive refresh with current properties

Pull Request checklist:

  • I've named my PR in the form of "Fixes #issue. Terse description."
  • My code follows the style guidelines of Terminal.Gui
  • My code follows the Terminal.Gui library design guidelines
  • I ran dotnet test before commit
  • I have made corresponding changes to the API documentation (using /// style comments)
  • My changes generate no new warnings
  • I have checked my code and corrected any poor grammar or misspellings
  • I conducted basic QA to assure all features are working

Copilot AI and others added 30 commits October 3, 2025 19:04
tig and others added 5 commits March 12, 2026 14:14
…/12e

Replace Application.QuitKey, ArrangeKey, NextTabKey, PrevTabKey,
NextTabGroupKey, PrevTabGroupKey with Application.DefaultKeyBindings
dictionary (Dictionary<Command, PlatformKeyBinding>).

Add Application.GetDefaultKey(Command) and GetDefaultKeys(Command)
helper methods. Add DefaultKeyBindingsChanged event.

Update all consumers: library, examples (~35 files), tests (~15 files),
config schema, and documentation (~9 files).

Fix parallel test race conditions in KeyboardTests and
ApplicationKeyboardThreadSafetyTests caused by static state mutation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix FormatDefaultKeyBindings to use Key instead of string for iteration
- Update Focused bindings to show all commands per key binding
- Fix stale cref warnings for removed IKeyboard properties

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Left: App/View default bindings (Dim.Auto width, 50/50 split)
- Middle: All View types list (Dim.Auto width)
- Right: HotKey/Focused bindings for selected type (Dim.Auto width)
- Uses reflection to enumerate all View subclasses
- Instantiates selected type to show its bindings

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Convert all remaining Bind.All/AllPlus/NonWindows string args to Key types
- Update example_config.json: fix schema URL, Driver.Force16Colors,
  PopoverMenu.DefaultKey, add Suspend/Key.Separator/MenuBar.DefaultKey,
  rename ColorSchemes to Schemes, move Glyphs inside theme
- Fix stale doc references in keyboard.md, config.md, navigation.md,
  newinv2.md, arrangement.md, menus.md, migratingfromv1.md
- Fix KeyboardTests.KeyBindings_Remove_Removes for parallel safety

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tig tig marked this pull request as ready for review March 12, 2026 22:11
@tig tig requested a review from Copilot March 12, 2026 22:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a configurable, layered “default key bindings” system across Terminal.Gui (Application-level + base View-level + per-view overrides), migrates many views/tests/docs away from the old per-key properties (e.g., Application.QuitKey) to Application.DefaultKeyBindings + Application.GetDefaultKey(Command), and adds a new Draw tracing category with additional draw-phase trace points.

Changes:

  • Add PlatformKeyBinding + Bind helpers and wire JSON (de)serialization + schema/docs/examples for key-binding configuration.
  • Introduce View.ApplyKeyBindings(...), add View.DefaultKeyBindings / View.ViewKeyBindings, and refactor multiple views to use layered key binding application.
  • Add TraceCategory.Draw and instrument draw/layout paths with draw tracing; expand unit tests accordingly.

Reviewed changes

Copilot reviewed 143 out of 143 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
Tests/UnitTestsParallelizable/Views/TreeViewDefaultKeyBindingsTests.cs New tests for TreeView<T>.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/TimeEditorDefaultKeyBindingsTests.cs New tests for TimeEditor.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/TextViewDefaultKeyBindingsTests.cs New tests for TextView.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/TextValidateFieldDefaultKeyBindingsTests.cs New tests for TextValidateField.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/TextFieldDefaultKeyBindingsTests.cs New tests for TextField.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/TabViewDefaultKeyBindingsTests.cs New tests for TabView.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/TableViewDefaultKeyBindingsTests.cs New tests for TableView.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/PopoverMenuDefaultKeyBindingsTests.cs New tests for PopoverMenu.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/NumericUpDownDefaultKeyBindingsTests.cs New tests for NumericUpDown<T>.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/MenuBarTests.cs Update tests to use GetDefaultKey(Command.Quit) + F10 activation
Tests/UnitTestsParallelizable/Views/MenuBarItemWithoutPopoverTests.cs Update tests from F9→F10 activation
Tests/UnitTestsParallelizable/Views/MenuBarDefaultKeyBindingsTests.cs New tests for MenuBar/PopoverMenu defaults + DropDownList toggle keys
Tests/UnitTestsParallelizable/Views/ListViewDefaultKeyBindingsTests.cs New tests for ListView.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/LinearRangeDefaultKeyBindingsTests.cs New tests for LinearRange<T>.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/HexViewDefaultKeyBindingsTests.cs New tests for HexView.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/DropDownListDefaultKeyBindingsTests.cs New tests for DropDownList.DefaultKeyBindings
Tests/UnitTestsParallelizable/Views/DateEditorDefaultKeyBindingsTests.cs New tests for DateEditor.DefaultKeyBindings
Tests/UnitTestsParallelizable/ViewBase/Keyboard/ViewDefaultKeyBindingsTests.cs New tests for View.DefaultKeyBindings + View.ViewKeyBindings
Tests/UnitTestsParallelizable/ViewBase/Keyboard/ApplyKeyBindingsTests.cs New tests covering View.ApplyKeyBindings behavior
Tests/UnitTestsParallelizable/ViewBase/ArrangementTests.cs Update comment to new arrange key API
Tests/UnitTestsParallelizable/Tracing/TraceTests.cs Add tests for new TraceCategory.Draw
Tests/UnitTestsParallelizable/Input/Keyboard/PlatformKeyBindingTests.cs New tests for PlatformKeyBinding behavior + JSON
Tests/UnitTestsParallelizable/Input/Keyboard/KeyBindingSchemaTests.cs New JSON schema round-trip tests for bindings dictionaries
Tests/UnitTestsParallelizable/Input/Keyboard/BindTests.cs New tests for Bind helper methods + platform detection
Tests/UnitTestsParallelizable/Drivers/Keyboard/KeyCodeTests.cs Update QuitKey comparison to GetDefaultKey(Command.Quit)
Tests/UnitTestsParallelizable/Configuration/SourcesManagerTests.cs Switch config test from QuitKey to a different setting key
Tests/UnitTestsParallelizable/Configuration/DeepClonerTests.cs Update deep clone test to use Application.DefaultKeyBindings config property
Tests/UnitTestsParallelizable/Application/Popover/Application.PopoverTests.cs Update to GetDefaultKey(Command.Quit)
Tests/UnitTestsParallelizable/Application/Keyboard/ApplicationKeyboardThreadSafetyTests.cs Adjust thread-safety tests to mutate DefaultKeyBindings
Tests/UnitTestsParallelizable/Application/Keyboard/ApplicationDefaultKeyBindingsTests.cs New tests for Application.DefaultKeyBindings content/shape
Tests/UnitTestsParallelizable/Application/InitTests.cs Update init tests to new key binding config pattern
Tests/UnitTestsParallelizable/Application/ApplicationImplTests.cs Use GetDefaultKey(Command.Quit) for quitting
Tests/UnitTests/Views/StatusBarTests.cs Update shortcuts and key events to GetDefaultKey(Command.Quit)
Tests/UnitTests/UICatalog/ScenarioTests.cs Update quit key retrieval in scenario loop
Tests/UnitTests/Configuration/ThemeManagerTests.cs Update config property key referenced in size estimation
Tests/UnitTests/Configuration/SourcesManagerTests.cs Update config source test JSON key
Tests/UnitTests/Configuration/SettingsScopeTests.cs Update SettingsScope tests to new key-binding config shape
Tests/StressTests/ScenariosStressTests.cs Update diagnostics message to GetDefaultKey(Command.Quit)
Tests/IntegrationTests/FluentTests/TestContextKeyEventTests.cs Update quit key injection to GetDefaultKey(Command.Quit)
Tests/IntegrationTests/FluentTests/PopverMenuTests.cs Update quit key usage and screenshots
Tests/IntegrationTests/FluentTests/MenuBarTests.cs Update MenuBar default activation key to F10 + quit key
Tests/IntegrationTests/FluentTests/FileDialogTests.cs Update quit key to GetDefaultKey(Command.Quit)
Tests/AppTestHelpers/AppTestHelper.Navigation.cs Update focus navigation to use GetDefaultKey(Command.NextTabStop)
Terminal.sln Add config example files to solution items
Terminal.Gui/Views/TreeView/TreeView.cs Add TreeView<T>.DefaultKeyBindings + apply layered bindings
Terminal.Gui/Views/TextInput/TimeEditor.cs Add TimeEditor.DefaultKeyBindings (intended view layer)
Terminal.Gui/Views/TextInput/TextValidateField.cs Add TextValidateField.DefaultKeyBindings + apply layered bindings
Terminal.Gui/Views/TextInput/TextField/TextField.Commands.cs Add TextField.DefaultKeyBindings + apply layered bindings
Terminal.Gui/Views/TextInput/DateEditor.cs Add DateEditor.DefaultKeyBindings (intended view layer)
Terminal.Gui/Views/TabView/TabView.cs Add TabView.DefaultKeyBindings + apply layered bindings
Terminal.Gui/Views/TableView/TableView.cs Add TableView.DefaultKeyBindings + apply layered bindings; refactors
Terminal.Gui/Views/NumericUpDown.cs Add NumericUpDown<T>.DefaultKeyBindings + apply layered bindings
Terminal.Gui/Views/MessageBox.cs Update docs to new quit-key API naming
Terminal.Gui/Views/Menu/PopoverMenu.cs Add PopoverMenu.DefaultKeyBindings + apply layered bindings
Terminal.Gui/Views/Menu/MenuBarItem.cs Update quit-key handling to new API
Terminal.Gui/Views/Menu/MenuBar.cs Add MenuBar.DefaultKeyBindings, change default activation to F10, update quit key
Terminal.Gui/Views/ListView/ListView.Commands.cs Add ListView.DefaultKeyBindings + apply layered bindings
Terminal.Gui/Views/LinearRange/LinearRange.cs Add LinearRange<T>.DefaultKeyBindings + apply layered bindings
Terminal.Gui/Views/HexView.cs Add HexView.DefaultKeyBindings + apply layered bindings
Terminal.Gui/Views/DropDownList.cs Add DropDownList.DefaultKeyBindings + apply layered bindings
Terminal.Gui/Views/DialogTResult.cs Update docs referencing quit key
Terminal.Gui/Views/Dialog.cs Update docs referencing quit key
Terminal.Gui/ViewBase/View.Navigation.cs Update docs to remove reliance on removed IKeyboard key properties
Terminal.Gui/ViewBase/View.Keyboard.cs Add View.DefaultKeyBindings, View.ViewKeyBindings, and ApplyKeyBindings
Terminal.Gui/ViewBase/View.Drawing.cs Add draw-phase trace points
Terminal.Gui/ViewBase/Navigation/TabBehavior.cs Update doc comment for tab-group key
Terminal.Gui/ViewBase/Adornment/Arranger.cs Use Application.GetDefaultKey(Command.Arrange)
Terminal.Gui/Resources/config.json Remove old per-key app defaults (QuitKey/ArrangeKey/tab keys)
Terminal.Gui/Input/Keyboard/PlatformKeyBinding.cs New PlatformKeyBinding type with per-platform key arrays
Terminal.Gui/Input/Keyboard/Bind.cs New factory helpers for PlatformKeyBinding
Terminal.Gui/Drivers/TuiPlatform.cs New platform enum used by binding resolution
Terminal.Gui/Drivers/PlatformDetection.cs Add GetCurrentPlatform() + obsolete string API
Terminal.Gui/Configuration/SourceGenerationContext.cs Register new key-binding types for source-gen serialization
Terminal.Gui/Configuration/KeyArrayJsonConverter.cs Add JSON converter for Key[] as string arrays
Terminal.Gui/App/Tracing/TraceCategory.cs Add Draw flag and include in All
Terminal.Gui/App/Tracing/Trace.cs Add Trace.Draw(...) and a new keyboard-binding trace overload
Terminal.Gui/App/Popovers/PopoverImpl.cs Use GetDefaultKey(Command.Quit) to dismiss popovers
Terminal.Gui/App/Popovers/IPopover.cs Update docs to new quit-key API naming
Terminal.Gui/App/Legacy/Application.Keyboard.cs Update usings around legacy keyboard facade
Terminal.Gui/App/Keyboard/IKeyboard.cs Remove per-key properties from IKeyboard interface
Terminal.Gui/App/Keyboard/ApplicationKeyboard.cs Bind application keys from Application.DefaultKeyBindings
Terminal.Gui/App/ApplicationImpl.Screen.cs Add layout/draw tracing at application level
Terminal.Gui/App/ApplicationImpl.Lifecycle.cs Remove syncing of deleted IKeyboard per-key properties
Terminal.Gui/App/Application.cs Replace per-key statics with DefaultKeyBindings + GetDefaultKey(s)
Examples/UICatalog/UICatalogRunnable.cs Add UI toggles for Configuration/Draw tracing; update quit shortcut
Examples/UICatalog/Scenarios/Unicode.cs Update quit shortcut key
Examples/UICatalog/Scenarios/TreeViewFileSystem.cs Update Quit menu key
Examples/UICatalog/Scenarios/TreeUseCases.cs Update status bar Quit key
Examples/UICatalog/Scenarios/TextViewAutocompletePopup.cs Update status bar Quit key
Examples/UICatalog/Scenarios/TabViewExample.cs Update status bar Quit key
Examples/UICatalog/Scenarios/TableEditor.cs Update status bar Quit key
Examples/UICatalog/Scenarios/SyntaxHighlighting.cs Update status bar Quit key
Examples/UICatalog/Scenarios/SingleBackgroundWorker.cs Update Quit key handling
Examples/UICatalog/Scenarios/ScrollBarDemo.cs Update title Quit key text
Examples/UICatalog/Scenarios/RunTExample.cs Update title Quit key text
Examples/UICatalog/Scenarios/PosAlignDemo.cs Update title Quit key text
Examples/UICatalog/Scenarios/MultiColouredTable.cs Update status bar Quit key
Examples/UICatalog/Scenarios/Menus.cs Update hotkey quit binding
Examples/UICatalog/Scenarios/MenuBarsWithoutPopovers.cs Update Quit menu item key
Examples/UICatalog/Scenarios/MenuBars.cs Update hotkey quit binding
Examples/UICatalog/Scenarios/ListColumns.cs Update status bar Quit key
Examples/UICatalog/Scenarios/Links.cs Update status bar Quit key
Examples/UICatalog/Scenarios/InteractiveTree.cs Update status bar Quit key
Examples/UICatalog/Scenarios/Images.cs Update title Quit key text
Examples/UICatalog/Scenarios/Editor.cs Update status bar Quit key
Examples/UICatalog/Scenarios/DynamicStatusBar.cs Update title Quit key text
Examples/UICatalog/Scenarios/CsvEditor.cs Update status bar Quit key
Examples/UICatalog/Scenarios/ConfigurationEditor.cs Update Quit shortcut key
Examples/UICatalog/Scenarios/CollectionNavigatorTester.cs Update Quit menu item key
Examples/UICatalog/Scenarios/CharacterMap/CharacterMap.cs Update Quit menu label text
Examples/UICatalog/Scenarios/Arrangement.cs Update demo keystrokes to new arrange key API
Examples/UICatalog/Scenario.cs Update helper text and quit logging
Examples/UICatalog/Properties/launchSettings.json Change default debug log level arg
Examples/ShortcutTest/ShortcutTest.cs Update title Quit key text
Examples/SelfContained/Program.cs Update title Quit key text + add using
Examples/ReactiveExample/LoginView.cs Update title Quit key text + add using
Examples/NativeAot/Program.cs Update title Quit key text + add using
Examples/Example/Example.cs Update title Quit key text + add using
Examples/FSharpExample/Program.fs Update title Quit key text
Examples/Config/windows.json New Windows-style key-binding config example
Examples/Config/README.md New documentation for config examples
Examples/Config/macos.json New macOS-style key-binding config example
Examples/Config/example_config.json Update example config schema URL + new key-binding layout
Examples/CommunityToolkitExample/LoginView.cs Update title Quit key text + add using
docfx/schemas/tui-config-schema.json Update schema to include Application.DefaultKeyBindings
docfx/includes/navigation-lexicon.md Update navigation lexicon to new commands/config
docfx/includes/arrangement-lexicon.md Update arrangement lexicon to new commands/config
docfx/docs/Popovers.md Update popover docs to new quit-key API naming
docfx/docs/newinv2.md Update docs snippets to new key-binding configuration API
docfx/docs/navigation.md Update navigation docs to new commands/config
docfx/docs/migratingfromv1.md Update migration docs to new quit-key configuration API
docfx/docs/menus.md Update menu docs for F10 activation + new quit-key API naming
docfx/docs/config.md Update config docs for new key-binding configuration model
docfx/docs/arrangement.md Update arrangement docs to new arrange key configuration model

You can also share your feedback on Copilot code review. Take the survey.

Comment thread Terminal.Gui/Views/NumericUpDown.cs
Comment thread Terminal.Gui/App/ApplicationImpl.Screen.cs
Comment thread Terminal.Gui/Views/TreeView/TreeView.cs
Comment thread Terminal.Gui/Views/ListView/ListView.Commands.cs
Comment thread Terminal.Gui/ViewBase/View.Keyboard.cs
Comment thread Terminal.Gui/App/Tracing/Trace.cs
Comment thread docfx/docs/config.md
Comment thread docfx/docs/migratingfromv1.md
Comment thread Terminal.Gui/Views/TextInput/TimeEditor.cs
Comment thread Terminal.Gui/Views/TextInput/DateEditor.cs
@tig tig changed the title Fixes #3023. Configurable key bindings via ConfigurationManager Fixes #3023 - BREAKING CHANGE - Configurable key bindings via ConfigurationManager Mar 12, 2026
tig and others added 5 commits March 12, 2026 17:50
…ests

Init_Dispose_Resets_Instance_Properties was mutating the static
Application.DefaultKeyBindings dictionary (setting NextTabGroup=Key.B,
PreviousTabGroup=Key.A, Quit=Key.C) without restoring the originals.
This caused NextTabGroupKey_DefaultValue_IsF6 and
PrevTabGroupKey_DefaultValue_IsShiftF6 to see corrupted state when
running in parallel.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Introduce ApplicationKeyboardThreadSafetyTests to verify thread-safety under various concurrent scenarios, including concurrent addition, invocation, event subscription, property mutation, and disposal. Tests use multiple threads to stress the API and assert no unexpected exceptions occur. Shared/static state is restored after tests to prevent side effects. This ensures ApplicationKeyboard is robust against race conditions in multi-threaded environments.
- Move all tests that mutate static state (e.g., Application.DefaultKeyBindings, Trace) into dedicated, non-parallelizable files/namespaces to prevent cross-test interference.
- Move and update TestLogging helper to UnitTests.Parallelizable for consistent logging in tests.
- Clean up KeyboardTests.cs by relocating setter tests to KeyboardSetterTests.cs.
- Add try/finally blocks to restore static state in tests that mutate it.
- Update usings and namespaces for clarity and parallelization.
- Add comments and safeguards to prevent accidental static state pollution.
- Enable safe parallel execution for the majority of the test suite, improving reliability and performance.
The Keyboard directory exclusion was preventing moved test files from being
discovered by the test runner.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… generic type names, fix ListView layer order, apply DateEditor/TimeEditor bindings, update docs

- Make Bind class public so consumers can configure DefaultKeyBindings
- Fix Trace.Keyboard to use string.Join instead of .ToString() on IEnumerable
- Strip generic arity suffix in ApplyKeyBindings (TreeView\1 -> TreeView)
- Fix ListView to apply its layer before base layer (Home/End override)
- Add ApplyKeyBindings call in DateEditor/TimeEditor constructors
- Update DefaultKeyBindingsChanged doc noting mutation limitation
- Fix config.md JSON examples to use proper nested structure
- Update TreeView/ListView comments for clarity

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tig tig requested review from BDisp and tznind March 13, 2026 12:49
@tig
Copy link
Copy Markdown
Member Author

tig commented Mar 13, 2026

@tznind what are your thoughts on this new design?

Comment thread Examples/UICatalog/Scenarios/KeyBindings.cs
Copy link
Copy Markdown
Collaborator

@BDisp BDisp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This very arduous work seems perfect to me. I only asked a question.

Comment thread Terminal.Gui/Drivers/PlatformDetection.cs Outdated
tig added 3 commits March 13, 2026 13:57
- Use explicit EventArgs<T> and ValueChangedEventArgs<T> in event invocations for clarity and type safety.
- Replace Tracing.Trace with Trace for tracing calls; add global using for Terminal.Gui.Tracing.
- Remove obsolete PlatformDetection.GetCurrentPlatformName and its test.
- Clean up unused usings and improve code consistency.
Refactored DriverRegistry for conciseness by using expression-bodied members and single-line record declarations. Updated built-in driver registration to a more compact style. Changed GetDefaultDriver to return the "ANSI" driver by default on Windows platforms instead of the "WINDOWS" driver.
@tig
Copy link
Copy Markdown
Member Author

tig commented Mar 13, 2026

This very arduous work seems perfect to me. I only asked a question.

Since I forgto before, I also made ansi the default driver on all patforms here.,

@tig tig merged commit 15aec41 into v2_develop Mar 13, 2026
11 checks passed
@tig tig deleted the feature/cm-keybindings branch March 13, 2026 23:33
tig added a commit to tig/Terminal.Gui that referenced this pull request Mar 24, 2026
Resolves merge conflicts from v2_develop changes:
- gui-cs#4836: Lazy Adornment Views (IAdornment + IAdornmentView split)
- gui-cs#4835: Adornment transparency
- gui-cs#4824: Configurable key bindings
- gui-cs#4845: Test project restructuring

Adapted TabView/TabRow to new AdornmentImpl architecture:
- Padding.Add -> Padding.GetOrCreateView().Add
- Border.Frame -> Border.GetFrame()
- Border.GetBorderRectangle -> BorderView.GetBorderBounds (made internal)
- Adornment type refs -> AdornmentView/AdornmentImpl
- Added LineCanvas merge from Border/Padding SubViews into parent View
- Fixed nullable LineStyle conversion in TabRow

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable overriding default Key Bindings with ConfigurationManager

5 participants